package cn.renxuan.repository;

import java.sql.Connection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

import cn.renxuan.entity.Entity;
import cn.renxuan.querys.BaseQuery;
import cn.renxuan.util.TriFunction;

/*
 * 数据库基础访问接口
 */
public interface IBaseRepository<TEntity extends Entity<TPrimaryKey>, TPrimaryKey> extends IRepository {

        /**
         * 事务处理
         * 
         * @param action 要在事务中执行的操作
         * @return CompletableFuture 包含事务执行结果
         * @param <TResult> 返回结果类型
         */
        public <TResult> CompletableFuture<TResult> transactionProcess(
                        Function<Connection, CompletableFuture<TResult>> action);

        /**
         * 事务处理
         * 
         * @param action 要在事务中执行的操作
         * @param level  隔离级别 (默认为 REPEATABLE_READ)
         * @return CompletableFuture 包含事务执行结果
         * @param <TResult> 返回结果类型
         */
        public <TResult> CompletableFuture<TResult> transactionProcess(
                        Function<Connection, CompletableFuture<TResult>> action,
                        int level);

        /**
         * 事务处理
         * 
         * @param action                  要在事务中执行的操作
         * @param transactioningPreAction 要在事务开启后预处理执行的操作
         * @param level                   隔离级别 (默认为 REPEATABLE_READ)
         * @return CompletableFuture 包含事务执行结果
         * @param <TResult> 返回结果类型
         */
        public <TPreResult, TResult> CompletableFuture<TResult> transactionProcess(
                        BiFunction<Connection, TPreResult, CompletableFuture<TResult>> action,
                        Function<Connection, CompletableFuture<TPreResult>> transactioningPreAction,
                        int level);

        /**
         * 事务处理
         * 
         * @param action                    要在事务中执行的操作
         * @param transactioningPreAction   要在事务开启后预处理执行的操作
         * @param transactioningAfterAction 要在事务处理主处理程序之后执行的操作
         * @param level                     隔离级别 (默认为 REPEATABLE_READ)
         * @return CompletableFuture 包含事务执行结果
         * @param <TResult> 返回结果类型
         */
        public <TPreResult, TResult, TAfterResult> CompletableFuture<TAfterResult> transactionProcess(
                        BiFunction<Connection, TPreResult, CompletableFuture<TResult>> action,
                        Function<Connection, CompletableFuture<TPreResult>> transactioningPreAction,
                        TriFunction<Connection, TPreResult, TResult, CompletableFuture<TAfterResult>> transactioningAfterAction,
                        int level);

        /**
         * 获取指定查询条件的实体分页列表（返回总记录数与泛型类型集合）
         * 
         * @param <TResult>
         * @param querys
         * @param clazz
         * @param tableName
         * @param fieldNames
         * @param conn
         * @param appendWhereAction
         * @param tableAlias
         * @return
         * @throws Exception
         */
        public <TResult> CompletableFuture<Map.Entry<Integer, List<TResult>>> getNewResultPageList(
                        BaseQuery<TEntity> querys,
                        Class<TResult> clazz,
                        String tableName,
                        String fieldNames,
                        Connection conn,
                        Consumer<AppendWhereActionParam<TEntity>> appendWhereAction,
                        String tableAlias) throws Exception;

        public <TResult> CompletableFuture<Map.Entry<Integer, List<TResult>>> getNewResultPageList(
                        BaseQuery<TEntity> querys,
                        Class<TResult> clazz,
                        String tableName,
                        String fieldNames,
                        Consumer<AppendWhereActionParam<TEntity>> appendWhereAction,
                        String tableAlias) throws Exception;

        /**
         * 获取指定查询条件的实体分页列表（返回总记录数与实体类型集合）
         * 
         * @param querys
         * @return
         * @throws Exception
         */
        public CompletableFuture<Map.Entry<Integer, List<TEntity>>> getNewPageList(BaseQuery<TEntity> querys)
                        throws Exception;

        public CompletableFuture<Map.Entry<Integer, List<TEntity>>> getNewPageList(BaseQuery<TEntity> querys,
                        String tableName,
                        String fieldNames,
                        Consumer<AppendWhereActionParam<TEntity>> appendWhereAction,
                        String tableAlias) throws Exception;

        public CompletableFuture<Map.Entry<Integer, List<TEntity>>> getNewPageList(BaseQuery<TEntity> querys,
                        String tableName,
                        String fieldNames,
                        Connection conn,
                        Consumer<AppendWhereActionParam<TEntity>> appendWhereAction,
                        String tableAlias) throws Exception;

        /**
         * 获取指定查询条件的实体列表带锁查询
         * 
         * @param <TResult>
         * @param querys
         * @param clazz
         * @param tableName
         * @param fieldNames
         * @param conn
         * @param appendWhereAction
         * @param tableAlias
         * @param lockType
         * @return
         * @throws Exception
         */
        public <TResult> CompletableFuture<List<TResult>> getNewListForLock(
                        BaseQuery<TEntity> querys,
                        Class<TResult> clazz,
                        String tableName,
                        String fieldNames,
                        Connection conn,
                        Consumer<AppendWhereActionParam<TEntity>> appendWhereAction,
                        String tableAlias,
                        EMySqlLockType lockType) throws Exception;

        /**
         * 新增实体
         * 
         * @param entityClaszz  实体对象的class对象
         * @param entity        实体对象
         * @param ignoreColumns 忽略添加的字段
         * @return CompletableFuture<Integer> 返回受影响的行数
         */
        public CompletableFuture<Integer> addAsync(Class<TEntity> entityClaszz, TEntity entity,
                        List<String> ignoreColumns)
                        throws Exception;

        /**
         * 新增记录并且返回自增id
         * 
         * @param entityClaszz  添加对象的class对象
         * @param entity        添加的对象
         * @param ignoreColumns 忽略添加的字段
         * @return 返回自增id
         * @throws Exception
         */
        public CompletableFuture<Number> addAndRetIdAsync(Class<TEntity> entityClaszz, TEntity entity,
                        List<String> ignoreColumns) throws Exception;

        /**
         * 新增记录并且返回自增id
         * 
         * @param entityClaszz  添加对象的class对象
         * @param entity        添加的对象
         * @param conn          数据库连接对象
         * @param ignoreColumns 忽略添加的字段
         * @return 返回自增id
         */
        public CompletableFuture<Number> addAndRetIdAsync(Class<TEntity> entityClaszz, TEntity entity,
                        Connection conn, List<String> ignoreColumns);

        /**
         * 批量新增并返回受影响的行数
         * 
         * @param entityClaszz  添加对象的class对象
         * @param entities      添加的对象集合
         * @param ignoreColumns 忽略添加的字段
         * @return 受影响的行数
         * @throws Exception
         */
        public CompletableFuture<Integer> batchAddAsync(Class<TEntity> entityClaszz, List<TEntity> entities,
                        List<String> ignoreColumns) throws Exception;

        /**
         * 批量新增并返回受影响的行数
         * 
         * @param entityClaszz  添加对象的class对象
         * @param entities      添加的对象集合
         * @param ignoreColumns 忽略添加的字段
         * @param step          插入数据的步长
         * @return 受影响的行数
         * @throws Exception
         */
        public CompletableFuture<Integer> batchAddAsync(Class<TEntity> entityClaszz, List<TEntity> entities,
                        List<String> ignoreColumns, int step) throws Exception;

        /**
         * 批量新增并返回受影响的行数
         * 
         * @param entityClaszz  添加对象的class对象
         * @param entities      添加的对象集合
         * @param conn          数据库连接对象
         * @param ignoreColumns 忽略添加的字段
         * @param step          插入数据的步长
         * @return 受影响的行数
         */
        public CompletableFuture<Integer> batchAddAsync(Class<TEntity> entityClaszz, List<TEntity> entities,
                        List<String> ignoreColumns,
                        Connection conn) throws Exception;

        /**
         * 批量新增并返回受影响的行数
         * 
         * @param entityClaszz  添加对象的class对象
         * @param entities      添加的对象集合
         * @param ignoreColumns 忽略添加的字段
         * @param conn          数据库连接对象
         * @param step          插入数据的步长
         * @return 受影响的行数
         */
        public CompletableFuture<Integer> batchAddAsync(Class<TEntity> entityClaszz, List<TEntity> entities,
                        List<String> ignoreColumns, Connection conn, int step);

}
